﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using Entidades.Responses;

namespace Agente.App_Code
{
    public class SystemInfo
    {
        private static SystemInfo instancia;        
        private const int BYTESTOMB = 1048576;
        private const int BYTESTOGB = 1073741824;
        private PerformanceCounter cpu;
        private PerformanceCounter ram;
        private DriveInfo[] discos;

        [DllImport("kernel32.dll")]
        public static extern void GlobalMemoryStatus(out MemoryStatus stat);

        public struct MemoryStatus
        {
            public uint Length;
            public uint MemoryLoad;
            public uint TotalPhysical;
            public uint AvailablePhysical;
            public uint TotalPageFile;
            public uint AvailablePageFile;
            public uint TotalVirtual;
            public uint AvailableVirtual;
        }

        public static SystemInfo GetInstance()
        {
            if (instancia == null)
            {
                instancia = new SystemInfo();
            }
            return instancia;
        }

        private SystemInfo()
        {
            cpu = new PerformanceCounter();
            cpu.CategoryName = "Processor";
            cpu.CounterName = "% Processor Time";
            cpu.InstanceName = "_Total";
        }

        #region Memoria 
        private float ObtenerRamTotal()
        {
            float capacidad = 0;
            MemoryStatus status = new MemoryStatus();
            GlobalMemoryStatus(out status);

            capacidad = status.TotalPhysical / BYTESTOMB;
            return capacidad;
        }

        private float ObtenerRamLibre()
        {
            float capacidad = 0;
            ram = new PerformanceCounter("Memory", "Available MBytes");
            capacidad = ram.NextValue();
            return capacidad;
        }

        public MemoryResponse ObtenerRam()
        {
            MemoryResponse mem = new MemoryResponse();
            mem.RamLibre = ObtenerRamLibre();
            mem.RamTotal = ObtenerRamTotal();
            return mem;
        }
        #endregion

        #region Disco 
        private long ObtenerDiscoTotal()
        {
            long capacidad = 0;
            discos = DriveInfo.GetDrives();
            foreach (DriveInfo disco in discos)
            {
                if (disco.IsReady)
                    capacidad += disco.TotalSize / BYTESTOGB;
            }
            return capacidad;
        }

        private long ObtenerDiscoLibre()
        {
            long capacidad = 0;
            discos = DriveInfo.GetDrives();
            foreach (DriveInfo disco in discos)
            {
                if (disco.IsReady)
                    capacidad += disco.TotalFreeSpace / BYTESTOGB;
            }
            return capacidad;
        }
        public DiscoResponse ObtenerDisco()
        {
            DiscoResponse disco = new DiscoResponse();
            disco.CapacidadLibre = ObtenerDiscoLibre();
            disco.CapacidadTotal = ObtenerDiscoTotal();
            return disco;
        }
        #endregion

        #region Cpu 
        private float ObtenerUsoCPU()
        {
            return cpu.NextValue();
        }
        public CpuResponse ObtenerCPU()
        {
            CpuResponse cpu = new CpuResponse();
            cpu.CpuUsage = ObtenerUsoCPU();
            return cpu;
        }
        #endregion
    }
}
